let _Vue = null
export default class VueRouter {
  static install (Vue) {
    // 1、判断当前插件是否已经被安装
    if (VueRouter.install.installed) {
      return
    }
    VueRouter.install.installed = true
    // 2、把Vue构造函数记录到全局变量
    _Vue = Vue
    // 3、把创建Vue实例时候传入的router对象注入到Vue实例上
    // _Vue.prototype.$router = this.$options.router 这行代码中的this指向VueRouter，所以不能这样写
    // 使用Vue的混入方法
    _Vue.mixin({
      beforeCreate () {
        // 将router注入到Vue实例操作只需要做一次，初始化组件的时候不需要进行此操作，router只有在
        if (this.$options.router) {
          _Vue.prototype.$router = this.$options.router // 此时的this指向的是Vue的实例
          this.$options.router.init()
        }
      }
    })
  }

  constructor (options) {
    this.options = options
    this.routeMap = {}
    this.data = _Vue.observable({
      current: '#/'
    })
  }

  init () {
    this.createRouteMap()
    this.initComponents(_Vue)
    this.initEvent()
  }

  createRouteMap () {
    // 遍历所有的路由规则，把路由规则解析成键值对的形式，存储到routeMap中
    this.options.routes.forEach(route => {
      this.routeMap[`#${route.path}`] = route.component
    })
  }

  initComponents (Vue) {
    const _this = this
    Vue.component('router-link', {
      // template: '<a :href="to"><slot></slot></slot></a>', // 这样写不行，因为这个项目中的vue是不带compiler的，因此无法编译template模板
      render (h) {
        return h('a', {
          attrs: {
            href: `#${this.to}`
          }
        }, [this.$slots.default])
      },
      props: {
        to: String
      }
    })

    Vue.component('router-view', {
      render (h) {
        const component = _this.routeMap[_this.data.current] || _this.routeMap['#*']
        return h(component)
      }
    })
  }

  initEvent () {
    window.addEventListener('hashchange', () => {
      this.data.current = window.location.hash
    })
  }
}
